/*
 * Copyright © 2004-2014 chenYuan. All rights reserved.
 * @Website:wwww.jspx.net
 * @Mail:39793751@qq.com
 * @author: chenYuan , 陈原
 * @License: Jspx.net Framework Code is open source (LGPL)，Jspx.net Framework 使用LGPL 开源授权协议发布。
 * @jvm:jdk1.6+  x86/amd64
 *
 */
package com.jspx.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.math.BigDecimal;
import java.util.Date;

/**
 * Created by IntelliJ IDEA.
 * User:chenYuan (mail:39793751@qq.com)
 * Date: 2007-4-13
 * Time: 8:50:52
 */
public class ObjectUtil {
    private static final Logger log = LoggerFactory.getLogger(ObjectUtil.class);

    private ObjectUtil() {

    }

    public static Object deepCopy(Object oldValue) throws IOException {
        if (oldValue == null) return null;
        Object newValue = null;
        ObjectOutputStream oos = null;
        ObjectInputStream ois = null;
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        try {
            oos = new ObjectOutputStream(bout);
            oos.writeObject(oldValue);
            ois = new ObjectInputStream(new ByteArrayInputStream(bout.toByteArray()));
            newValue = ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            log.error("Error deepCopy  during serialization and deserialization of value:" + oldValue.getClass(), e);
        } finally {
            try {
                if (oos != null) {
                    oos.close();
                }
                if (ois != null) {
                    ois.close();
                }
            } catch (Exception e) {
                log.error("Error closing Stream");
            }
        }
        return newValue;

    }

    public static long getSerializedSize(Object obj) {
        if (obj == null) return 0;
        if (!(obj instanceof Serializable)) {
            return 0;
        }
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(bout);
            oos.writeObject(obj);
            return bout.size();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (oos != null) {
                    oos.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return 0;
    }

    /**
     * @param o 对像
     * @return boolean 逻辑类型
     */
    public static boolean toBoolean(Object o) {
        if (o == null) return false;
        if (o instanceof Boolean) {
            return (Boolean)o;
        }
        if (o instanceof Long) {
            return  (Long)o>0;
        }
        if (o instanceof Float) {
            return  (Float)o>0;
        }
        if (o instanceof Double) {
            return  (Double)o>0;
        }
        if (o instanceof Integer) {
            return (Integer)o > 0;
        }
        return StringUtil.toBoolean(o.toString());
    }

    /**
     *
     * @param obj 对象
     * @return 整数
     */
    public static int toInt(Object obj) {
        if (obj == null) return 0;
        if (obj instanceof Boolean) {
            if ((Boolean) obj) {
                return 1;
            } else {
                return 0;
            }
        }
        if (obj.getClass().isAssignableFrom(Integer.class))
        {
            return  ((Integer) obj);
        }
        if (obj.getClass().isAssignableFrom(Long.class))
        {
            return ((Long)obj).intValue();
        }
        if (obj.getClass().isAssignableFrom(Double.class))
        {
            return  ((Double) obj).intValue();
        }
        if (obj.getClass().isAssignableFrom(Float.class))
        {
            return  ((Float) obj).intValue();
        }
        if (obj.getClass().isAssignableFrom(BigDecimal.class))
        {
            return  ((BigDecimal) obj).intValue();
        }
        return StringUtil.toInt(obj.toString());
    }

    /**
     * 
     * @param obj 对象
     * @return 长整
     */
    public static long toLong(Object obj) {
        if (obj == null) return 0;
        if (obj.getClass().isAssignableFrom(Long.class))
       {
           return  ((Long) obj);
        }
        if (obj.getClass().isAssignableFrom(Double.class))
        {
            return  ((Double) obj).longValue();
        }
        if (obj.getClass().isAssignableFrom(Integer.class))
        {
            return  ((Integer) obj).longValue();
        }
        if (obj.getClass().isAssignableFrom(BigDecimal.class))
        {
            return  ((BigDecimal) obj).longValue();
        }
        if (obj.getClass().isAssignableFrom(Date.class))
        {
            Date d = (Date) obj;
            return d.getTime();
        }
        return StringUtil.toLong(obj.toString());
    }

    /**
     * 
     * @param obj 对象
     * @return d单进度
     */
    public static float toFloat(Object obj) {
        if (obj == null) return 0;
        if (obj.getClass().isAssignableFrom(Float.class))
        {
            return  ((Float) obj);
        }
        if (obj.getClass().isAssignableFrom(Double.class))
        {
            return  ((Double) obj).floatValue();
        }
        if (obj.getClass().isAssignableFrom(Long.class))
        {
            return  ((Long) obj).floatValue();
        }
        if (obj.getClass().isAssignableFrom(Integer.class))
        {
            return  ((Integer) obj).floatValue();
        }
        if (obj.getClass().isAssignableFrom(BigDecimal.class))
        {
            return  ((BigDecimal) obj).floatValue();
        }
        return StringUtil.toFloat(obj.toString());
    }

    /**
     * @param obj 对象
     * @return 双精度
     */
    public static double toDouble(Object obj) {
        if (obj == null) return 0;
        if (obj.getClass().isAssignableFrom(Long.class))
        {
            return  ((Long) obj).doubleValue();
        }
        if (obj.getClass().isAssignableFrom(Integer.class))
        {
            return  ((Integer) obj).doubleValue();
        }
        if (obj.getClass().isAssignableFrom(Float.class))
        {
            return  ((Float) obj).doubleValue();
        }
        if (obj.getClass().isAssignableFrom(BigDecimal.class))
        {
            return  ((BigDecimal) obj).doubleValue();
        }
        return StringUtil.toDouble(obj.toString());
    }

    public static Date toDate(Object obj) {
        if (obj == null) return DateUtil.empty;
        if (obj.getClass().isAssignableFrom(Date.class))
        {
            return  (Date) obj;
        }
        if (obj.getClass().isAssignableFrom(Long.class))
        {
            return  new Date(((Long) obj));
        }
        if (obj.getClass().isAssignableFrom(java.sql.Date.class))
        {
            return  new Date(((java.sql.Date) obj).getTime());
        }
        try {
            return StringUtil.toDate(obj.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return DateUtil.empty;
    }

    public static java.sql.Date toSqlDate(Object obj) {
        if (obj == null) return new java.sql.Date(DateUtil.empty.getTime());
        if (obj.getClass().isAssignableFrom(java.sql.Date.class))
        {
            return  ((java.sql.Date) obj);
        }
        if (obj.getClass().isAssignableFrom(Long.class))
        {
            return  new java.sql.Date(((Long) obj));
        }
        if (obj.getClass().isAssignableFrom(Date.class))
        {
            return  new java.sql.Date(((Date) obj).getTime());
        }
        try {
            Date date = StringUtil.toDate(obj.toString());
            return  new java.sql.Date(date.getTime());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new java.sql.Date(DateUtil.empty.getTime());
    }
    public static java.sql.Timestamp toSqlTimestamp(Object obj) {
        if (obj == null) return new java.sql.Timestamp(DateUtil.empty.getTime());

        if (obj.getClass().isAssignableFrom(java.sql.Timestamp.class))
        {
            return  ((java.sql.Timestamp) obj);
        }
        if (obj.getClass().isAssignableFrom(Long.class))
        {
            return  new java.sql.Timestamp(((Long) obj));
        }
        if (obj.getClass().isAssignableFrom(Date.class))
        {
            return  new java.sql.Timestamp(((Date) obj).getTime());
        }
        try {
            Date date = StringUtil.toDate(obj.toString());
            return  new java.sql.Timestamp(date.getTime());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new java.sql.Timestamp(DateUtil.empty.getTime());
    }


     public static String toString(Object obj) {
        if (obj == null) return StringUtil.empty;
         return obj.toString();
    }

    private static byte[] serialize(Object object) {
        ObjectOutputStream objectOutputStream = null;
        ByteArrayOutputStream byteArrayOutputStream = null;
        try {
            byteArrayOutputStream = new ByteArrayOutputStream();
            objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(object);
            return byteArrayOutputStream.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static Object unSerizlize(byte[] binaryByte) {
        ObjectInputStream objectInputStream = null;
        ByteArrayInputStream byteArrayInputStream = null;
        byteArrayInputStream = new ByteArrayInputStream(binaryByte);
        try {
            objectInputStream = new ObjectInputStream(byteArrayInputStream);
            return objectInputStream.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}